package com.example.guesswho.data.local

import android.content.Context
import com.example.guesswho.data.parse.AudienceChat
import com.example.guesswho.data.parse.Question
import com.example.guesswho.data.parse.Room
import com.example.guesswho.data.parse.ShortLink
import kotlinx.coroutines.flow.Flow

class LocalDataSource private constructor(context: Context) {
    private val database = AppDatabase.getDatabase(context)
    private val questionDao = database.questionDao()
    private val roomDao = database.roomDao()
    private val audienceChatDao = database.audienceChatDao()
    private val shortLinkDao = database.shortLinkDao()

    // Question operations
    fun getAllAuditedQuestions(): Flow<List<QuestionEntity>> = questionDao.getAllAuditedQuestions()
    
    fun getQuestionsByCategory(category: String): Flow<List<QuestionEntity>> = 
        questionDao.getQuestionsByCategory(category)
    
    fun getQuestionsByDifficulty(difficulty: Int): Flow<List<QuestionEntity>> = 
        questionDao.getQuestionsByDifficulty(difficulty)
    
    suspend fun getQuestionById(objectId: String): QuestionEntity? = 
        questionDao.getQuestionById(objectId)
    
    suspend fun cacheQuestions(questions: List<Question>) {
        val entities = questions.map { question ->
            QuestionEntity(
                objectId = question.objectId,
                title = question.title,
                coverUrl = question.coverUrl,
                voiceUrl = question.voiceUrl,
                options = question.options,
                answerIndex = question.answerIndex,
                category = question.category,
                difficulty = question.difficulty,
                isAudited = question.isAudited
            )
        }
        questionDao.insertQuestions(entities)
    }
    
    suspend fun cacheQuestion(question: Question) {
        val entity = QuestionEntity(
            objectId = question.objectId,
            title = question.title,
            coverUrl = question.coverUrl,
            voiceUrl = question.voiceUrl,
            options = question.options,
            answerIndex = question.answerIndex,
            category = question.category,
            difficulty = question.difficulty,
            isAudited = question.isAudited
        )
        questionDao.insertQuestion(entity)
    }

    // Room operations
    fun getAllRooms(): Flow<List<RoomEntity>> = roomDao.getAllRooms()
    
    fun getRoomsByStatus(status: String): Flow<List<RoomEntity>> = roomDao.getRoomsByStatus(status)
    
    fun getAvailableRoomsByDifficulty(difficulty: Int): Flow<List<RoomEntity>> = 
        roomDao.getAvailableRoomsByDifficulty(difficulty)
    
    suspend fun getRoomById(objectId: String): RoomEntity? = roomDao.getRoomById(objectId)
    
    suspend fun cacheRooms(rooms: List<Room>) {
        val entities = rooms.map { room ->
            RoomEntity(
                objectId = room.objectId,
                difficulty = room.difficulty,
                status = room.status,
                userIds = room.users.map { it.objectId },
                unansweredCount = room.unansweredCount,
                createdAt = room.createdAt
            )
        }
        roomDao.insertRooms(entities)
    }
    
    suspend fun cacheRoom(room: Room) {
        val entity = RoomEntity(
            objectId = room.objectId,
            difficulty = room.difficulty,
            status = room.status,
            userIds = room.users.map { it.objectId },
            unansweredCount = room.unansweredCount,
            createdAt = room.createdAt
        )
        roomDao.insertRoom(entity)
    }

    // Audience Chat operations
    fun getChatsByRoomId(roomId: String): Flow<List<AudienceChatEntity>> = 
        audienceChatDao.getChatsByRoomId(roomId)
    
    suspend fun getRecentChatsByRoomId(roomId: String, limit: Int = 50): List<AudienceChatEntity> = 
        audienceChatDao.getRecentChatsByRoomId(roomId, limit)
    
    suspend fun cacheChat(chat: AudienceChat) {
        val entity = AudienceChatEntity(
            objectId = chat.objectId,
            roomId = chat.roomId,
            username = chat.username,
            text = chat.text,
            ts = chat.ts
        )
        audienceChatDao.insertChat(entity)
    }
    
    suspend fun cacheChats(chats: List<AudienceChat>) {
        val entities = chats.map { chat ->
            AudienceChatEntity(
                objectId = chat.objectId,
                roomId = chat.roomId,
                username = chat.username,
                text = chat.text,
                ts = chat.ts
            )
        }
        audienceChatDao.insertChats(entities)
    }

    // Short Link operations
    suspend fun getShortLinkByCode(code: String): ShortLinkEntity? = 
        shortLinkDao.getShortLinkByCode(code)
    
    suspend fun getShortLinksByRoomId(roomId: String): List<ShortLinkEntity> = 
        shortLinkDao.getShortLinksByRoomId(roomId)
    
    suspend fun cacheShortLink(shortLink: ShortLink) {
        val entity = ShortLinkEntity(
            code = shortLink.code,
            roomId = shortLink.roomId
        )
        shortLinkDao.insertShortLink(entity)
    }

    companion object {
        @Volatile
        private var INSTANCE: LocalDataSource? = null

        fun getInstance(context: Context): LocalDataSource {
            return INSTANCE ?: synchronized(this) {
                val instance = LocalDataSource(context)
                INSTANCE = instance
                instance
            }
        }
    }
}